kitt_score 0.1.0

Decision engine at the core of Project KITT — in-memory stateful matching with pluggable scoring backends.
Documentation
# Identifiers and Time

This note covers `src/ids.rs` and `src/clock.rs`.

## `LocId`

**Defined in:** `src/ids.rs`

A newtype over `u64` representing a caller-assigned location identifier.

### Role
- primary key into the location table,
- stable handle used by all event types,
- deliberately opaque to the engine.

### Why it matters
Using a newtype prevents mixing location ids with action ids at compile time while remaining zero-cost at runtime.

### Relationships
- used by [[Modules/Events#StateUpdate]], [[Modules/Events#ActionIngest]], and [[Modules/Events#Trigger]],
- keys the [[Modules/Location State#LocationTable]].

## `ActionId`

**Defined in:** `src/ids.rs`

A newtype over `u64` representing a caller-assigned action identifier.

### Role
- identifies one registered action within a location,
- echoed in [[Modules/Engine and Decision#Outcome]].

### Relationships
- enters through [[Modules/Events#ActionIngest]],
- stored in [[Modules/Location State#ActionEntry]],
- copied into [[Modules/Scoring Core#Candidate]].

## `KindId`

**Defined in:** `src/ids.rs`

A newtype over `u16` representing the interned id of a kind name.

### Role
- compact runtime handle for kind lookup,
- index into the schema's kind table,
- used for slot resolution.

### Relationships
- produced by [[Modules/Schema#SchemaBuilder]],
- carried by [[Modules/Events#KindRef]] and [[Modules/Location State#LocationDef]].

## `AttrId`

**Defined in:** `src/ids.rs`

A newtype over `u16` representing the interned id of an attribute name.

### Role
- compact runtime handle for one schema attribute,
- used to resolve a [[Modules/Schema#Slot]].

### Relationships
- carried inside [[Modules/Events#AttrSet]],
- resolved through [[Modules/Schema#SlotLayout]].

## `UnixTime`

**Defined in:** `src/ids.rs`

A type alias for `i64` meaning seconds since the Unix epoch.

### Role
- action validity windows use it for `start` and `end`,
- clocks return it,
- expiry logic compares actions against it.

## `Clock`

**Defined in:** `src/clock.rs`

A trait with one method: `now() -> UnixTime`.

### Role
This is the engine's time source abstraction. It keeps expiry deterministic under tests and lets callers inject different time strategies.

### Relationships
- stored in [[Modules/Engine and Decision#EngineConfig]],
- used by `Engine::ingest_trigger`.

## `SystemClock`

**Defined in:** `src/clock.rs`

The production implementation of [[#Clock]].

### Behavior
- wraps `SystemTime::now()`,
- converts to Unix seconds,
- clamps pathological pre-epoch values to `0` instead of panicking.

### Why that clamp exists
Expiry logic depends on a usable timestamp. If the system clock is broken, returning `0` is safer than crashing the engine.

## `TestClock`

**Defined in:** `src/clock.rs`

A test-oriented clock backed by `AtomicI64`.

### API
- `TestClock::at(t)` creates a clock at a chosen time and returns it in `Arc<Self>`.
- `advance(secs)` moves time forward.
- `set(t)` forces an exact time.

### Role
This type is the foundation for deterministic expiry tests and scenario tests.

### Relationships
- used in `tests/integration_expiry.rs`, `tests/integration_metrics.rs`, and the scenario test added for this wiki.

## Design summary

The id types and clock abstraction are small, but they are foundational:
- ids make the rest of the API type-safe,
- the clock makes the engine predictable and testable.